/* Name : Antimatter
 * Author: Tom Dickman
 * Date: 5-3-12
 * Description: Antimatter prevents the user from building wormholes. It is placed randomly at the start of
 *  a new round and stays in the same position permanently.
 * Revisions: See Subversion logs at http://code.google.com/p/software-engineering-2012/source/list
 */

import java.awt.Graphics2D;
import java.util.Iterator;
import java.util.LinkedList;

public class Antimatter extends Item {
	private static LinkedList<Antimatter> idList = new LinkedList<Antimatter>();
	private Sprite sprite;
	private int spriteX[];
	private int spriteY[];
	private int xMomentum[];
	private int yMomentum[];
	private float spriteRot[];
	private float spriteRotSpeed[];
	private float spriteScale[];
	private int totSprites;
	
	// Places the Antimatter randomly in the room, preventing collisions and impossible scenarios. Initializes graphics.
	public Antimatter() {
		Game.create((Item)this, 10); // Needed for update, draw, and destroy
		colType = COL_LINE; // Needed for collision checking
		idList.add(this); // Needed for collision checking
		sprite = Sprite.load("/sprites/Antimatter/Antimatter0.png");
		int attempt = 0;
		do {
			x = Game.randomInt(GameScreen.getWidth());
			y = Game.randomInt(GameScreen.getHeight());
			double dir = Game.randomFloat((float) (2.0f*Math.PI));
			int dis = Game.randomInt(400)+200;
			x2 = (int) (x + dis*Math.cos(dir));
			y2 = (int) (y + dis*Math.sin(dir));
			r = Game.randomInt(45,55);
		} while (Planet.checkCollision(this, false)!=0 || Nebula.checkCollision(this, false)!=0 || 
				AsteroidField.checkCollision(this, false)!=0 || Antimatter.checkCollision(this, false)!=0 ||
				Wormhole.checkCollision(this, false) != 0 || !GameScreen.isGameWinnable() || ++attempt >= 30);
		if (attempt >= 30) {
			GameScreen.throwRoomCreationError();
		}
		
		float lineLength = (float)Math.sqrt(Math.pow(x2-x,2)+Math.pow(y2-y,2));
		totSprites = (int) Math.ceil(lineLength / (r-20)) + 1;
		spriteX = new int[totSprites];
		spriteY = new int[totSprites];
		xMomentum = new int[totSprites];
		yMomentum = new int[totSprites];
		spriteRot = new float[totSprites];
		spriteRotSpeed = new float[totSprites];
		spriteScale = new float[totSprites];
		
		float dx = (x2-x)/(totSprites-1);
		float dy = (y2-y)/(totSprites-1);
		final float SPRITE_RADIUS = 112;
		float scaleFactor = (r-20) / SPRITE_RADIUS;
		for (int i=0; i<totSprites; i++) {
			xMomentum[i] = 0;
			yMomentum[i] = 0;
			spriteRot[i] = Game.randomFloat((float) (Math.PI*2.0f));
			spriteRotSpeed[i] = Game.randomFloat(-0.1f, 0.1f);
			spriteScale[i] = Game.randomFloat(0.8f*scaleFactor, 1.0f*scaleFactor);
			spriteX[i] = (int) (x + dx*i);
			spriteY[i] = (int) (y + dy*i);
		}
		for (int i = totSprites-1; i > 0; i--) {
			int randIndex = Game.randomInt(i+1);
			int tmpX = spriteX[i];
			int tmpY = spriteY[i];
			spriteX[i] = spriteX[randIndex];
			spriteY[i] = spriteY[randIndex];
			spriteX[randIndex] = tmpX;
			spriteY[randIndex] = tmpY;
		}
	}
	
	// Called every frame: Updates sprite positions and checks for collisions with Planets
	public void update() {
		Planet.checkCollision(this, true);
		
		// Draw Update
		for (int i = 0; i < totSprites; i++) {			
			xMomentum[i] += Game.randomInt(-1, 2);
			if (xMomentum[i] > 10) {xMomentum[i] = 10;}
			if (xMomentum[i] < -10) {xMomentum[i] = -10;}
			yMomentum[i] += Game.randomInt(-1, 2);
			if (yMomentum[i] > 10) {yMomentum[i] = 10;}
			if (yMomentum[i] < -10) {yMomentum[i] = -10;}
			
			spriteRotSpeed[i] = spriteRotSpeed[i]*0.8f + Game.randomFloat(-0.1f, 0.1f)*0.2f;
			spriteRot[i] += spriteRotSpeed[i];
		}
	}
	
	// Sets any colliding Wormholes to invalid
	public void collision(Item other) {
		if (other instanceof Wormhole){
			Wormhole cOther = (Wormhole)other;
			cOther.setPlacementValidity(false);	
		}
	}
	
	// Called when destroyed: removes self from Antimatter list
	public void destroy() {
		idList.remove(this); // Needed for collision checking
	}
	
	// Called every frame: Draws all sprites making up the Antimatter
	public void draw() {
		Graphics2D gh = Game.getGraphicsHandle();		
		for (int i = 0; i < totSprites; i++) {			
			sprite.draw(gh, spriteX[i]+xMomentum[i], spriteY[i]+yMomentum[i], spriteRot[i], spriteScale[i]);
		}
	}
	
	// Function needed in each item class for collision checking
	public static int checkCollision(Item other, Boolean notify) {
		int num = 0;
	    for(Iterator it = idList.iterator(); it.hasNext();) {
	    	Item idOn = (Item)it.next();
			if (idOn != other) {
				if (Item.intersection(other, idOn)) {
					if (notify) {
						idOn.collision(other);
					}
					num++;
				}
			}
		}
		return num;
	}
}
